﻿using System.Collections.Generic;
using System.Linq;

namespace Borg.Framework
{
    public static class SlotInfoEx
    {
        public static void CreateAndPlug(SlotInfo slot)
        {
            if (!slot.LazyLoad && slot.AutoPlug || slot.RegisteredPlugTypeInfos.Count == 0)
                return;

            PlugInfo pi;
            var list = new List<PlugTypeInfo>();
            
            using (var enumerator = slot.PluggedPlugInfos.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    pi = enumerator.Current;

                    if (!list.Contains(pi.PlugTypeInfo))
                        list.Add(pi.PlugTypeInfo);
                }
            }

            foreach (var pti in slot.RegisteredPlugTypeInfos.Where(pti => !list.Contains(pti)))
            {
                pi = pti.CreateExtension(slot);

                if (!(slot.AutoPlug && !slot.Unique))
                    pi.Plug(slot);
            }
        }

        public static PlugInfo FindPluggedPlug(SlotInfo slot, string extName)
        {
            return slot.PluggedPlugInfos.
                FirstOrDefault(pi => pi.PlugTypeInfo.ExtensionTypeInfo.Name.Equals(extName));
        }

        public static PlugInfo FindPluggedPlug(SlotInfo slot, string param, string value)
        {
            return slot.PluggedPlugInfos.
                FirstOrDefault(pi => pi.PlugTypeInfo.GetParamValue(param).Equals(value));
        }

        public static PlugTypeInfo FindRegisteredPlug(SlotInfo slot, string extName)
        {
            return slot.RegisteredPlugTypeInfos.
                FirstOrDefault(pti => pti.ExtensionTypeInfo.Name.Equals(extName));
        }

        public static PlugTypeInfo FindRegisteredPlug(SlotInfo slot, string param, string value)
        {
            return slot.RegisteredPlugTypeInfos.
                FirstOrDefault(pti => pti.GetParamValue(param).Equals(value));
        }

        public static ExtensionInfo FindUniqueExtension(SlotInfo slot, ExtensionTypeInfo extType)
        {
            return extType.ExtensionInfos.FirstOrDefault(ei => ei.Owner == slot);
        }

        public static PlugInfo GetPluggedPlug(this SlotInfo slot, PlugTypeInfo plugType)
        {
            return slot.PluggedPlugInfos.FirstOrDefault(pi => pi.PlugTypeInfo == plugType);
        }

        public static bool IsPlugged(this SlotInfo slot, PlugTypeInfo plugType)
        {
            return (slot.GetPluggedPlug(plugType) != null);
        }
    }
}

